using StackExchange.Redis;
using Zhaoxi.Zhihu.HotService.Data;

namespace Zhaoxi.Zhihu.HotService.Core;

public class HotRankManager(IConnectionMultiplexer redis)
{
    private readonly IDatabase _db = redis.GetDatabase();
    private const int FollowWeight = 100;
    private const int AnswerWeight = 20;
    private const int LikeWeight = 1;
    private const int Viewweight = 1;

    /// <summary>
    /// 计算热度值
    /// </summary>
    /// <param name="stat"></param>
    /// <returns></returns>
    private static int CalcHeatValue(QuestionStat stat)
    {
        return stat.FollowCount * FollowWeight
               + stat.ViewCount * Viewweight
               + stat.AnswerCount * AnswerWeight
               + stat.LikeCount * LikeWeight;
    }

    /// <summary>
    /// 创建热榜值
    /// </summary> 
    /// <param name="questionStats"></param>
    public async Task CreateHotRankAsync(Dictionary<int, QuestionStat> questionStats)
    {
        var sortedSetEntries = questionStats
            .Select(stat => new SortedSetEntry(stat.Key, CalcHeatValue(stat.Value)))
            .ToArray();
        await _db.SortedSetAddAsync(RedisConstant.HotRanking, sortedSetEntries);
    }

    /// <summary>
    /// 更新热榜数据
    /// </summary>
    /// <param name="???"></param>
    public async Task UpdateHotRankAsync(Dictionary<int, QuestionStat> questionStats)
    {
        var batch = _db.CreateBatch();
        var batchTasks = new List<Task>();

        foreach (var stat in questionStats)
        {
            var heatValue = CalcHeatValue(stat.Value);
            if (heatValue == 0) continue;
            batchTasks.Add(
                batch.SortedSetIncrementAsync(RedisConstant.HotRanking, stat.Key,
                    heatValue));
        }

        if (batchTasks.Count == 0) return;
        batch.Execute();
        await Task.WhenAll(batchTasks);
    }

    public async Task ClearHotRankAsync()
    {
        await _db.KeyDeleteAsync(RedisConstant.HotRanking);
    }
}